#ifndef IDE_HPP
#define IDE_HPP

#include<vector>
#include<map>
#include<iostream>
#include<functional>

using namespace std;

class endide{
public:
	int ret;
};

class ide;
typedef function<int(ide&,const vector<string>&,int)> command;

class ide{
	void explain(const string &cmd){
		vector<string> cmds;
		string temp;
		for(auto &ec:cmd){
			if(ec==' '){
				if(!temp.empty()){
					cmds.push_back(temp);
					temp=="";
				}
			}else{
				temp+=string(1,ec);
			}
		}
		if(!temp.empty()){
			cmds.push_back(temp);
			temp=="";
		}
		//split done
		
		for(int post=0;post<cmd.size();post++){
			if(commands.find(cmds[post])==commands.end()){
				cout<<"\033[31merror : "<<cmds[post]<<" is not a command known\033[0m\n";
				return;
			}
			post+=commands[cmds[post]](*this,cmds,post);
		}
	}
	int exitCode;
	string fina;
	map<string,command> commands;
	void InitCommands(){
		commands["quit"]=[](ide &self,const vector<string> &cmds,int post){
			throw endide{};
			return 0;
		};
		commands[":q"]=commands["quit"];
	}
public:
	ide(){
		exitCode=0;
		InitCommands();
	}
	void run(const string &filename=""){
		string input;
		fina=filename;
		try{
			while(1){
				cout<<filename<<
				(filename.empty()?"":" ")
				<<">>>"<<flush;
				getline(cin,input);
				explain(input);
				cout<<"\n";
			}
		}catch(const endide &e){
			exitCode=e.ret;
			return;
		}
	}
	const int &GetExitCode(){
		return exitCode;
	}
};

#endif